﻿using HomagGroup.Base.UI.Controls;
using Proxy;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using static Proxy.ProcessResourceInternal;

namespace Proxy
{
    public abstract class UseGraphHooks : HomagGroup.Base.UI.NotifyPropertyChangedBase
    {
        public abstract Canvas Element { get; set; }
        public abstract string ImageKey { get; set; }
        public abstract string StorageColor { get; set; }

        public abstract TimeSpan AnimationSeconds { get; set; }
        public abstract ObservableCollection<StorageSpaceModel> StorageSpaceList { get; set; }

        public ObservableCollection<BulletGraph> bulletGraphsList { get; set; } = new ObservableCollection<BulletGraph>();

        public int SuckersZindex { get; set; } = 40;

        public abstract void OnRefreshProgress();


        public void CreateStorageView()
        {
            OnUseDrawingStorage();
            OnUseDrawingSuckers();
            AddSuckersCooperation();
        }

        private void OnUseDrawingStorage()
        {
            foreach (var item in StorageSpaceList)
            {
                var rectangleCanvas = new Canvas
                {
                    Width = item.Storagewidth,
                    Height = item.StorageHeight
                };

                // 创建矩形（带公共阴影）
                var rectangle = CreateStorageRectangle(item);
                rectangleCanvas.Children.Add(rectangle);

                if (item.Storagetype != 6)
                {
                    AddStorageInfo(rectangleCanvas, item);
                    AddBulletGraph(rectangleCanvas, item);
                }

                PositionElement(rectangleCanvas, item);
                Element.Children.Add(rectangleCanvas);
            }
        }

        private void OnUseDrawingSuckers()
        {
            Line XaxleTop = CreateCanvasLine("XaxleTop", 610, 10, 680, 10, Brushes.Black, 3);
            Line Yaxle = CreateCanvasLine("Yaxle", 645, 10, 645, 490, Brushes.Black, 3);
            Line XaxleBottom = CreateCanvasLine("XaxleBottom", 610, 490, 680, 490, Brushes.Black, 3);

            Rectangle suckers = new Rectangle
            {
                Uid = "Suckers",
                Width = 70,
                Height = 70,
                Fill = GetResourceBrush("aim"),
            };
            Canvas.SetLeft(suckers, 610);
            Canvas.SetTop(suckers, 400);
            Canvas.SetZIndex(suckers, SuckersZindex + 10);
            Element.Children.Add(suckers);

            Rectangle board = new Rectangle
            {
                Uid = "Board",
                Width = 50,
                Height = 100,
                Fill = GetHexadecimalColor("#eaa300"),
                RenderTransformOrigin = new Point(0.5, 0.5),
                RenderTransform = new RotateTransform(0),
                Opacity = 0
            };

            Canvas.SetLeft(board, Canvas.GetLeft(suckers));
            Canvas.SetTop(board, Canvas.GetTop(suckers));
            Canvas.SetZIndex(board, SuckersZindex + 20);
            Element.Children.Add(board);

            Canvas.SetZIndex(XaxleTop, SuckersZindex);
            Element.Children.Add(XaxleTop);

            Canvas.SetZIndex(Yaxle, SuckersZindex);
            Element.Children.Add(Yaxle);

            Canvas.SetZIndex(XaxleBottom, SuckersZindex);
            Element.Children.Add(XaxleBottom);
        }

        public void OnMoveSuckersByStorage(StorageSpaceModel storageSpaceModel)
        {
            Line XaxleTop = Element.Children.OfType<Line>().First(x => x.Uid == "XaxleTop");
            Line Yaxle = Element.Children.OfType<Line>().First(x => x.Uid == "Yaxle");
            Line XaxleBottom = Element.Children.OfType<Line>().First(x => x.Uid == "XaxleBottom");
            Rectangle suckers = Element.Children.OfType<Rectangle>().First(x => x.Uid == "Suckers");

            double targetX = storageSpaceModel.Xposition + (storageSpaceModel.Storagewidth / 2);
            double targetY = storageSpaceModel.Yposition + (storageSpaceModel.StorageHeight / 2);

            double suckersCenterX = targetX - (suckers.Width / 2);
            double suckersCenterY = targetY - (suckers.Height / 2);

            // 创建动画故事板
            Storyboard storyboard = new Storyboard();
            TimeSpan duration = TimeSpan.FromSeconds(1);
            IEasingFunction ease = new CubicEase { EasingMode = EasingMode.EaseInOut };

            // X轴顶部线动画
            AddLineAnimation(storyboard, XaxleTop,
            targetX - 30, 5, // X1,Y1
            targetX + 30, 5, // X2,Y2
            duration, ease);

            // X轴底部线动画
            AddLineAnimation(storyboard, XaxleBottom,
            targetX - 30, 490,
            targetX + 30, 490,
            duration, ease);

            // Y轴线动画（水平移动）
            AddLineAnimation(storyboard, Yaxle,
            targetX, 7, // 新的X坐标保持垂直线
            targetX, 490,
            duration, ease);

            // 吸盘动画
            AddElementAnimation(storyboard, suckers,
            suckersCenterX, // Canvas.Left
            suckersCenterY, // Canvas.Top
            duration, ease);

            storyboard.Begin();
        }

        public void OnMoveSuckersByCoordinate(double targetX, double targetY, bool isBoard = true, double roateAngle = 0)
        {
            Line XaxleTop = Element.Children.OfType<Line>().First(x => x.Uid == "XaxleTop");
            Line Yaxle = Element.Children.OfType<Line>().First(x => x.Uid == "Yaxle");
            Line XaxleBottom = Element.Children.OfType<Line>().First(x => x.Uid == "XaxleBottom");
            Rectangle Suckers = Element.Children.OfType<Rectangle>().First(x => x.Uid == "Suckers");
            Rectangle Board = Element.Children.OfType<Rectangle>().First(x => x.Uid == "Board");

            double suckersCenterX = targetX - (Suckers.Width / 2);
            double suckersCenterY = targetY - (Suckers.Height / 2);

            double BoardCenterX = targetX - (Board.Width / 2);
            double BoardCenterY = targetY - (Board.Height / 2);

            // 动画
            Storyboard storyboard = new Storyboard();
            IEasingFunction ease = new CubicEase { EasingMode = EasingMode.EaseInOut };

            AddLineAnimation(storyboard, XaxleTop, targetX - 30, 10, targetX + 30, 10, AnimationSeconds, ease);

            AddLineAnimation(storyboard, XaxleBottom, targetX - 30, 490, targetX + 30, 490, AnimationSeconds, ease);

            AddLineAnimation(storyboard, Yaxle, targetX, 10, targetX, 490, AnimationSeconds, ease);

            AddElementAnimation(storyboard, Suckers, suckersCenterX, suckersCenterY, AnimationSeconds, ease);

            AddElementAnimation(storyboard, Board, BoardCenterX, BoardCenterY, AnimationSeconds, ease);

            AddBoardAnimation(storyboard, Board, roateAngle);

            storyboard.Completed += (s, e) =>
            {
                System.Threading.Thread.Sleep(200);
                Board.Opacity = isBoard ? 1 : 0;
            };

            storyboard.Begin();

            OnChangeSuckersCooperation(targetX, targetY);
        }

        public void OnChangeSuckersCooperation(double x, double y)
        {
            TextBlock suckersCooperation = Element.Children.OfType<TextBlock>().First(i => i.Uid == "SuckersCooperation");
            suckersCooperation.Text = "X:" + x.ToString() + "," + " Y:" + y.ToString();
        }

        private void AddSuckersCooperation()
        {
            Rectangle suckers = Element.Children.OfType<Rectangle>().First(x => x.Uid == "Suckers");
            double X = Canvas.GetLeft(suckers);
            double Y = Canvas.GetTop(suckers);

            TextBlock suckersCooperation = new TextBlock
            {
                Uid = "SuckersCooperation",
                Text = "X:" + X.ToString() + "," + " Y:" + Y.ToString(),
                FontSize = 15,
                Width = 150,
                Height = 20,
                FontWeight = FontWeights.Bold,
                TextAlignment = TextAlignment.Left,
                Foreground = Brushes.Red,
                Background = Brushes.White,
                Opacity = 0.7
            };
            Canvas.SetLeft(suckersCooperation, 5);
            Canvas.SetTop(suckersCooperation, 480);

            Canvas.SetZIndex(suckersCooperation, 100);
            Element.Children.Add(suckersCooperation);
        }

        private void AddBoardAnimation(Storyboard storyboard, UIElement element, double roateAngle)
        {
            DoubleAnimation roateAnimation = new DoubleAnimation
            {
                To = roateAngle,
                Duration = TimeSpan.FromSeconds(0.5),
                EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut },
            };
            Storyboard.SetTarget(roateAnimation, element);
            Storyboard.SetTargetProperty(roateAnimation, new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)"));
            storyboard.Children.Add(roateAnimation);
        }

        private void AddLineAnimation(Storyboard storyboard, Line line, double newX1, double newY1, double newX2, double newY2, TimeSpan duration, IEasingFunction ease)
        {
            AddAnimation(storyboard, line, Line.X1Property, newX1, duration, ease);
            AddAnimation(storyboard, line, Line.Y1Property, newY1, duration, ease);
            AddAnimation(storyboard, line, Line.X2Property, newX2, duration, ease);
            AddAnimation(storyboard, line, Line.Y2Property, newY2, duration, ease);
        }

        private void AddElementAnimation(Storyboard storyboard, UIElement element, double newLeft, double newTop, TimeSpan duration, IEasingFunction ease)
        {
            AddAnimation(storyboard, element, Canvas.LeftProperty, newLeft, duration, ease);
            AddAnimation(storyboard, element, Canvas.TopProperty, newTop, duration, ease);
        }

        private void AddAnimation<T>(Storyboard storyboard, DependencyObject target, DependencyProperty property, T toValue, TimeSpan duration, IEasingFunction ease)
        {
            DoubleAnimation animation = new DoubleAnimation
            {
                To = (double)(object)toValue,
                Duration = duration,
                EasingFunction = ease
            };

            Storyboard.SetTarget(animation, target);
            Storyboard.SetTargetProperty(animation, new PropertyPath(property));
            storyboard.Children.Add(animation);
        }

        private Line CreateCanvasLine(string id, double x1, double y1, double x2, double y2, Brush stroke, double strokeThickness)
        {
            return new Line
            {
                Uid = id,
                X1 = x1,
                Y1 = y1,
                X2 = x2,
                Y2 = y2,
                Stroke = stroke,
                StrokeThickness = strokeThickness
            };
        }

        private Rectangle CreateStorageRectangle(StorageSpaceModel item)
        {
            var fillBrush = item.Storagetype == 6 ? GetResourceBrush(ImageKey) : GetHexadecimalColor(StorageColor);

            if (fillBrush is ImageBrush imageBrush)
            {
                imageBrush.Stretch = Stretch.UniformToFill;
            }

            return new Rectangle
            {
                Uid = item.StorageCode,
                Width = item.Storagewidth,
                Height = item.StorageHeight,
                Fill = fillBrush,
                Stroke = item.Storagetype == 6 ? Brushes.Black : null
            };
        }

        private void AddStorageInfo(Canvas canvas, StorageSpaceModel item)
        {
            var storageCode = CreateTextBlock(
            text: "S" + item.StorageCode,
            fontSize: 28,
            left: 5,
            bottom: 0);

            var sizeInfo = CreateTextBlock(
            text: $"",//{item.Storagewidth}x{item.StorageHeight}
            fontSize: 12,
            width: item.Storagewidth,
            top: 3,
            textAlignment: TextAlignment.Center);

            canvas.Children.Add(storageCode);
            canvas.Children.Add(sizeInfo);
        }

        private void AddBulletGraph(Canvas canvas, StorageSpaceModel item)
        {
            var bulletGraph = new BulletGraph
            {
                Uid = item.StorageCode,
                Maximum = 100,
                Width = item.StorageHeight,
                Height = 10,
                Value = 0,
                Orientation = Orientation.Vertical,
                QualitativeRanges = new ObservableCollection<QualitativeRange>
                {
                    new QualitativeRange { Value=50, Color = EnumBulletGraphColor.Green },
                    new QualitativeRange { Value=80, Color = EnumBulletGraphColor.Yellow },
                    new QualitativeRange { Value=100, Color = EnumBulletGraphColor.Red }
                }
            };

            bulletGraphsList.Add(bulletGraph);
            Canvas.SetRight(bulletGraph, -18);
            Canvas.SetTop(bulletGraph, -8);
            Canvas.SetZIndex(bulletGraph, 2);
            canvas.Children.Add(bulletGraph);
        }

        private TextBlock CreateTextBlock(string text, double fontSize, double? width = null, double? left = null, double? top = null, double? bottom = null, TextAlignment textAlignment = TextAlignment.Left)
        {
            var tb = new TextBlock
            {
                Text = text,
                FontSize = fontSize,
                TextAlignment = textAlignment
            };

            if (width.HasValue) tb.Width = width.Value;
            if (left.HasValue) Canvas.SetLeft(tb, left.Value);
            if (top.HasValue) Canvas.SetTop(tb, top.Value);
            if (bottom.HasValue) Canvas.SetBottom(tb, bottom.Value);

            Canvas.SetZIndex(tb, 2);
            return tb;
        }

        private void PositionElement(Canvas element, StorageSpaceModel item)
        {
            Canvas.SetLeft(element, item.Xposition);
            Canvas.SetTop(element, item.Yposition);
        }
    }
}